/* CoralCube | Massively Multiplayer Online Role-Playing Game(MMORPG) Emulator.
|* 
|* Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
|*               2008-2010 TrinityCore <http://www.trinitycore.org/>
|*               2008-2010 CoralCube <http://www.CoralCube.com/>
|*
|* This program is free software. You can redistribute it and/or modify it under the terms of 
|* the GNU General Public License as published by the Free Software Foundation, either 
|* version 2 of the License.
|*
|* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, 
|* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
|* See the GNU General Public License for more details.
|*
|* You should have received a copy of the GNU General Public License along with this program. 
|* If not, see <http://www.gnu.org/licenses/>.
|*/

#ifndef CORE_MAP_INSTANCED_H
#define CORE_MAP_INSTANCED_H

#include "Map.h"
#include "InstanceSaveMgr.h"
#include "DBCEnums.h"

class MapInstanced : public Map
{
    friend class MapManager;
public:
    typedef UNORDERED_MAP< uint32, Map* > InstancedMaps;

    MapInstanced(uint32 id, time_t expiry);
    ~MapInstanced() { }

    // functions overwrite Map versions
    void Update(const uint32&);
    void DelayedUpdate(const uint32 diff);
    //void RelocationNotify();
    void UnloadAll();
    bool CanEnter(Player* player);

    Map* CreateInstance(const uint32 mapId, Player * player);
    Map* FindMap(uint32 InstanceId) const { return _FindMap(InstanceId); }
    bool DestroyInstance(InstancedMaps::iterator &itr);

    void AddGridMapReference(const GridPair &p)
    {
        ++GridMapReference[p.x_coord][p.y_coord];
        SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), true);
    }

    void RemoveGridMapReference(GridPair const& p)
    {
        --GridMapReference[p.x_coord][p.y_coord];
        if (!GridMapReference[p.x_coord][p.y_coord])
            SetUnloadReferenceLock(GridPair(63-p.x_coord, 63-p.y_coord), false);
    }

    InstancedMaps &GetInstancedMaps() { return m_InstancedMaps; }
    virtual void InitVisibilityDistance();

private:

    InstanceMap* CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty);
    BattlegroundMap* CreateBattleground(uint32 InstanceId, Battleground* bg);

    InstancedMaps m_InstancedMaps;

    Map* _FindMap(uint32 InstanceId) const
    {
        InstancedMaps::const_iterator i = m_InstancedMaps.find(InstanceId);
        return(i == m_InstancedMaps.end() ? NULL : i->second);
    }

    uint16 GridMapReference[MAX_NUMBER_OF_GRIDS][MAX_NUMBER_OF_GRIDS];
};
#endif
